package com.rain.builder;

import com.rain.bean.FieldInfo;
import com.rain.bean.TableInfo;
import com.rain.utils.Constants;
import com.rain.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.Introspector;
import java.io.*;
import java.util.List;
import java.util.Map;

public class BuildController {

    private static final Logger logger = LoggerFactory.getLogger(BuildService.class);

    public static void execute(TableInfo tableInfo) throws IOException {
        File folder = new File(Constants.PACKAGE_CONTROLLER_PATH);
        if(!folder.exists()){
            folder.mkdirs();
        }

        File file = new File(folder,tableInfo.getBeanName() + "Controller.java");

        try{
            file.createNewFile();
        }catch(IOException e){
            e.printStackTrace();
        }

        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;

        try{
            outputStream = new FileOutputStream(file);
            outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            // 基本模版
            bufferedWriter.write("package " + Constants.PACKAGE_CONTROLLER + ";");
            bufferedWriter.newLine();
            bufferedWriter.newLine();

            // 判断是否添加日期类
            if(tableInfo.getHaveDate() || tableInfo.getHaveDateTime()){
                bufferedWriter.write("import java.util.Date;");
                bufferedWriter.newLine();
                bufferedWriter.write(Constants.BEAN_DATE_FORMAT_CLASS + ";");
                bufferedWriter.newLine();
                bufferedWriter.write(Constants.BEAN_DATE_UNFORMAT_CLASS + ";");
                bufferedWriter.newLine();
                bufferedWriter.write("import " + Constants.PACKAGE_ENUM +".DateTimePatternEnum;");
                bufferedWriter.newLine();
                bufferedWriter.write("import " + Constants.PACKAGE_UTILS +".DateUtil;");
                bufferedWriter.newLine();

            }

            bufferedWriter.write("import " + Constants.PACKAGE_ENUM +".PageSize;");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + "." + "SimplePage" + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + ".ResponseVO");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_ENTITY + "." + tableInfo.getBeanName() + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanParamName() + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + "." + "PaginationResult" + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_SERVICE + "." + tableInfo.getBeanName() + "Service" + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import org.springframework.web.bind.annotation.*;");
            bufferedWriter.newLine();
            bufferedWriter.newLine();

            bufferedWriter.write("import javax.annotation.Resource;");
            bufferedWriter.newLine();
            bufferedWriter.write("import java.util.List;");
            bufferedWriter.newLine();

            BuildComment.createClassComment(bufferedWriter, tableInfo.getComment() + "Controller");
            bufferedWriter.newLine();
            bufferedWriter.write("@RestController\n");
            bufferedWriter.write("@RequestMapping(\"/" + Introspector.decapitalize(tableInfo.getBeanName() +"\")\n"));
            bufferedWriter.write("public class " + tableInfo.getBeanName() + "Controller" + " extends BaseController {\n\n");

            bufferedWriter.write("\t@Resource\n");
            bufferedWriter.write("\tprivate " + tableInfo.getBeanName() + "Service " + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ";\n\n");

            bufferedWriter.write("\t@GetMapping\n");
            bufferedWriter.write("\tpublic ResponseVO list(" + tableInfo.getBeanParamName() + " query) {\n");
            bufferedWriter.write("\t\treturn getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".findListByPage(query)" + ");\n");
            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"新增");
            bufferedWriter.write("\t@PostMapping\n");
            bufferedWriter.write("\tpublic ResponseVO add(" + tableInfo.getBeanName() + " bean) {\n\n");
            bufferedWriter.write("\treturn " + "getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".add(bean)" + ")" + ";\n\n");
            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"批量新增");
            bufferedWriter.write("\t@PostMapping(\"/addBatch\")\n");
            bufferedWriter.write("\tpublic ResponseVO addBatch(List<" + tableInfo.getBeanName() + "> listBean) {\n\n");
              bufferedWriter.write("\treturn " + "getSuccessResponseVO(" +  Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".addBatch(listBean)"  + ")" + ";\n\n");
            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"批量新增修改");
            bufferedWriter.write("\t@PostMapping(\"/addOrUpdateBatch\")\n");
            bufferedWriter.write("\tpublic ResponseVO addOrUpdateBatch(List<" + tableInfo.getBeanName() + "> listBean) {\n\n");
               bufferedWriter.write("\treturn " + "getSuccessResponseVO(" +  Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".addOrUpdateBatch(listBean)" + ")" + ";\n\n");
            bufferedWriter.write("\t}\n\n");

            for (Map.Entry<String, List<FieldInfo>> entry: tableInfo.getKeyIndexMap().entrySet()) {
                List<FieldInfo> value = entry.getValue();
                Integer index = 0;
                StringBuffer stringBufferName = new StringBuffer();
                StringBuffer stringBufferParam = new StringBuffer();
                StringBuffer stringBufferIdParam = new StringBuffer();
                StringBuffer stringBufferReturnParam = new StringBuffer();
                StringBuffer stringBufferMapping1 = new StringBuffer();
                for (FieldInfo fieldInfo : value) {
                    index++;
                    stringBufferName.append(StringUtils.uperCaseFirstLetter(fieldInfo.getPropertyName()));
                    if(index < value.size()){
                        stringBufferName.append("And");
                    }

                    stringBufferParam.append("@RequestParam " + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName());
                    stringBufferIdParam.append("@PathVariable " + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName());
                    stringBufferReturnParam.append(fieldInfo.getPropertyName());
                    stringBufferMapping1.append("\"" + fieldInfo.getPropertyName() + "\"");
                    if(index < value.size()){
                        stringBufferParam.append(", ");
                        stringBufferReturnParam.append(", ");
                        stringBufferMapping1.append(", ");
                    }
                }
                if(stringBufferReturnParam.toString().equals("id")) {
                    BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "查询");
                    //bufferedWriter.write("\t@RequestMapping(\"/" + "get"+ tableInfo.getBeanName() +"By" + stringBufferName + "\")\n");
                    bufferedWriter.write("\t@GetMapping(\"/{" + stringBufferReturnParam + "}\")\n");
                    bufferedWriter.write("\tpublic " + "ResponseVO" + " get"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferIdParam + ") {\n\n");
                    bufferedWriter.write("\t\treturn " + "getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".get"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferReturnParam + ")" + ")" + ";\n\n");
                    bufferedWriter.write("\t}\n\n");

                    BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "更新");
                    //bufferedWriter.write("\t@RequestMapping(\"/" + "update"+ tableInfo.getBeanName() +"By" + stringBufferName + "\")\n");
                    bufferedWriter.write("\t@PutMapping(\"/{" + stringBufferReturnParam + "}\")\n");
                    bufferedWriter.write("\tpublic ResponseVO update"+ tableInfo.getBeanName() +"By" + stringBufferName + "(@RequestBody " + tableInfo.getBeanName() + " bean, " + stringBufferIdParam + "){\n\n");
                    bufferedWriter.write("\t\treturn " + "getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".update"+ tableInfo.getBeanName() +"By" + stringBufferName + "(bean, " + stringBufferReturnParam + ")"  + ")" +  ";\n\n");

                    bufferedWriter.write("\t}\n\n");

                    BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "删除");
                    //bufferedWriter.write("\t@RequestMapping(\"/" + "delete"+ tableInfo.getBeanName() +"By" + stringBufferName + "\")\n");
                    bufferedWriter.write("\t@DeleteMapping(\"/{" + stringBufferReturnParam + "}\")\n");
                    bufferedWriter.write("\tpublic ResponseVO delete"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferIdParam + ") {\n\n");
                    bufferedWriter.write("\t\treturn " + "getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".delete"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferReturnParam + ")"  + ")" +  ";\n\n");

                } else {
                    BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "查询");
                    //bufferedWriter.write("\t@RequestMapping(\"/" + "get"+ tableInfo.getBeanName() +"By" + stringBufferName + "\")\n");
                    bufferedWriter.write("\t@GetMapping(params = {" + stringBufferMapping1 + "})\n");
                    bufferedWriter.write("\tpublic " + "ResponseVO" + " get"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferParam + ") {\n\n");
                    bufferedWriter.write("\t\treturn " + "getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".get"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferReturnParam + ")" + ")" + ";\n\n");
                    bufferedWriter.write("\t}\n\n");

                    BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "更新");
                    //bufferedWriter.write("\t@RequestMapping(\"/" + "update"+ tableInfo.getBeanName() +"By" + stringBufferName + "\")\n");
                    bufferedWriter.write("\t@PutMapping(params = {" + stringBufferMapping1 + "})\n");
                    bufferedWriter.write("\tpublic ResponseVO update"+ tableInfo.getBeanName() +"By" + stringBufferName + "(@RequestBody " + tableInfo.getBeanName() + " bean, " + stringBufferParam + "){\n\n");
                    bufferedWriter.write("\t\treturn " + "getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".update"+ tableInfo.getBeanName() +"By" + stringBufferName + "(bean, " + stringBufferReturnParam + ")"  + ")" +  ";\n\n");

                    bufferedWriter.write("\t}\n\n");

                    BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "删除");
                    //bufferedWriter.write("\t@RequestMapping(\"/" + "delete"+ tableInfo.getBeanName() +"By" + stringBufferName + "\")\n");
                    bufferedWriter.write("\t@DeleteMapping(params = {" + stringBufferMapping1 + "})\n");
                    bufferedWriter.write("\tpublic ResponseVO delete"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferParam + ") {\n\n");
                    bufferedWriter.write("\t\treturn " + "getSuccessResponseVO(" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") + ".delete"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferReturnParam + ")"  + ")" +  ";\n\n");
                }

                bufferedWriter.write("\t}\n\n");
            }

            bufferedWriter.write("}");


            bufferedWriter.flush();
        }catch (Exception e){
            logger.info("创建Service失败", e.getMessage());
            e.printStackTrace();
        }finally {
            if(bufferedWriter != null) {
                bufferedWriter.close();
            }
            if(outputStreamWriter != null) {
                outputStreamWriter.close();
            }
            if(outputStream != null) {
                outputStream.close();
            }
        }
    }
}
